package com.jk.hearthstone.core;

import com.jk.hearthstone.card.BaseCard;
import com.jk.hearthstone.card.arms.BaseArms;
import com.jk.hearthstone.card.biology.BaseBiology;
import com.jk.hearthstone.card.biology.entourage.BaseEntourage;
import com.jk.hearthstone.card.biology.hero.BaseHero;
import com.jk.hearthstone.card.magic.BaseMagic;
import com.jk.hearthstone.data.Action;
import com.jk.hearthstone.data.Desktop;
import com.jk.hearthstone.data.History;
import com.jk.hearthstone.enumeration.ActionType;

import static com.jk.hearthstone.enumeration.ActionType.*;

/**
 * 默认的控制器，控制游戏所有的基本动作动作与规则
 * @author jk
 */
public class DefaultController implements BaseController {

    /**
     * 出牌器(无选择对象)
     * @param card 打出的牌
     */
    @Override
    public boolean play(Desktop desktop,History history,BaseCard card){
        //出牌数量加一
        history.currentTurn.playNum += 1;
        desktop.myself.power -= card.cost;
        desktop.myCards.remove(card);
        history.currentTurn.actions.add(new Action(ACTION_TYPE_PLAY,card));
        if(card instanceof BaseEntourage){
            return play(desktop,history,(BaseEntourage)card);
        }
        else if(card instanceof BaseMagic){
            return play(desktop,history,(BaseMagic)card);
        }
        else if(card instanceof BaseArms){
            return play(desktop,history,(BaseArms)card);
        }
        else if(card instanceof BaseHero){
            return play(desktop,history,(BaseHero)card);
        }
        return false;
    }

    private boolean play(Desktop desktop,History history,BaseEntourage entourage){
        desktop.myEntourage.add(entourage);
        entourage.battleCry(desktop,history);
        return true;
    }

    private boolean play(Desktop desktop,History history,BaseMagic magic){
        //是否触发连击
        if(history.currentTurn.playNum>1){
            return magic.combo(desktop,history);
        }else {
           return magic.effect(desktop,history);
        }
    }

    private boolean play(Desktop desktop,History history,BaseArms arms){
        //如果当前装备了武器，则触发其亡语
        if(desktop.myself.arms != null){
            desktop.myself.arms.deadWords(desktop,history);
        }
        //装备武器，触发战吼
        arms.battleCry(desktop,history);
        desktop.myself.arms = arms;
        return true;
    }

    private boolean play(Desktop desktop,History history,BaseHero hero){
        return true;
    }


    /**
     * 出牌器(有选择对象)
     * @param card 打出的牌
     */
    @Override
    public boolean play(Desktop desktop,History history,BaseCard card,BaseBiology target){
        //出牌数量加一
        history.currentTurn.playNum += 1;
        desktop.myself.power -= card.cost;
        desktop.myCards.remove(card);
        history.currentTurn.actions.add(new Action(ACTION_TYPE_PLAY,card,target));
        if(card instanceof BaseEntourage){
            return play(desktop,history,(BaseEntourage)card,target);
        }
        else if(card instanceof BaseMagic){
            //触发释放法术后效果
            /*for (BaseEntourage entourage : desktop.myEntourage) {
                entourage.afterMagic(desktop,history);
            }*/
            return play(desktop,history,(BaseMagic)card,target);
        }
        else if(card instanceof BaseArms){
           return play(desktop,history,(BaseArms)card,target);
        }
        else if(card instanceof BaseHero){
            return play(desktop,history,(BaseHero)card,target);
        }
        return false;
    }

    private boolean play(Desktop desktop,History history,BaseEntourage entourage,BaseBiology target){
        return true;
    }

    private boolean play(Desktop desktop,History history,BaseMagic magic,BaseBiology target){
        //是否触发连击
        if(history.currentTurn.playNum>1){
            return magic.combo(desktop,history,target);
        }else {
            return magic.effect(desktop,history,target);
        }
    }

    private boolean play(Desktop desktop,History history,BaseArms arms,BaseBiology target){
        return true;
    }

    private boolean play(Desktop desktop,History history,BaseHero entourage,BaseBiology target){
        return true;
    }

    /**
     * 不带目标的英雄技能
     * @param hero
     */
    @Override
    public void skill(Desktop desktop,History history,BaseHero hero){
        hero.power -= hero.skillCost;
        hero.skill(desktop,history);
        hero.canSkill = false;
        history.currentTurn.actions.add(new Action(ACTION_TYPE_HEROSKILL,hero));
    }

    /**
     * 带目标的英雄技能
     * @param hero
     * @param target
     */
    @Override
    public void skill(Desktop desktop,History history,BaseHero hero,BaseBiology target){
        hero.power -= hero.skillCost;
        hero.skill(desktop,history,target);
        hero.canSkill = false;
        history.currentTurn.actions.add(new Action(ACTION_TYPE_HEROSKILL,hero,target));
    }


    /**
     * 公共攻击方法
     * @param attacker 攻击者
     * @param target 目标
     */
    @Override
    public void attack(Desktop desktop,History history,BaseBiology attacker, BaseBiology target){
        history.currentTurn.actions.add(new Action(ACTION_TYPE_ATTACK,attacker,target));
        //风怒的情况
        if(attacker instanceof BaseHero && ((BaseHero) attacker).arms!=null){
            if(((BaseHero) attacker).arms.attackNum>1){
                ((BaseHero) attacker).arms.attackNum -= 1;
            }else {
                ((BaseHero) attacker).canAttack = false;
            }
        }else if(attacker instanceof BaseEntourage){
            if(((BaseEntourage) attacker).attackNum>1){
                ((BaseEntourage) attacker).attackNum -= 1;
            }else {
                ((BaseEntourage) attacker).canAttack = false;
            }
        }
        //转发
        if(attacker instanceof BaseHero && target instanceof BaseHero){
            attack(desktop,history,(BaseHero)attacker,(BaseHero)target);
        }
        else if(attacker instanceof BaseHero && target instanceof BaseEntourage){
            attack(desktop,history,(BaseHero)attacker,(BaseEntourage)target);
        }
        else if(attacker instanceof BaseEntourage && target instanceof BaseHero){
            attack(desktop,history,(BaseEntourage)attacker,(BaseHero)target);
        }
        else if(attacker instanceof BaseEntourage && target instanceof BaseEntourage){
            attack(desktop,history,(BaseEntourage)attacker,(BaseEntourage)target);
        }
    }

    private void attack(Desktop desktop,History history,BaseHero attacker,BaseHero target){
        int att = attacker.att;
        //有武器的情况
        if(attacker.arms != null){
            att += attacker.arms.att;
            attacker.arms.durable -= 1;
            if(attacker.arms.durable==0){
                attacker.arms = null;
                attacker.arms.deadWords(desktop,history);
            }
        }
        hurt(desktop,history,target,att);
        //有吸血的情况
        if(attacker.arms != null && attacker.arms.bloodSucking){
            cure(desktop,history,attacker,att);
        }
    }

    private void attack(Desktop desktop,History history,BaseHero attacker,BaseEntourage target){
        int att = attacker.att;
        //有武器的情况
        if(attacker.arms != null){
            att += attacker.arms.att;
            attacker.arms.durable -= 1;
            if(attacker.arms.durable==0){
                attacker.arms = null;
                attacker.arms.deadWords(desktop,history);
            }
        }
        hurt(desktop,history,attacker,target.att);
        hurt(desktop,history,target,att);
        //有吸血的情况
        if(attacker.arms.bloodSucking){
            cure(desktop,history,attacker,att);
        }
        if(target.bloodSucking){
            cure(desktop,history,desktop.enemy,target.att);
        }
    }

    private void attack(Desktop desktop,History history,BaseEntourage attacker,BaseHero target){
        int att = attacker.att;
        hurt(desktop,history,target,att);
        //有吸血的情况
        if(attacker.bloodSucking){
            cure(desktop,history,desktop.myself,att);
        }
    }

    private void attack(Desktop desktop,History history,BaseEntourage attacker,BaseEntourage target){
        int att = attacker.att;
        hurt(desktop,history,attacker,target.att);
        hurt(desktop,history,target,att);
        //有吸血的情况
        if(attacker.bloodSucking){
            cure(desktop,history,desktop.myself,att);
        }
        if(target.bloodSucking){
            cure(desktop,history,desktop.enemy,target.att);
        }
    }


    /**
     * 公共的治疗方法
     * @param biology 治疗对象
     * @param num 治疗数值
     */
    @Override
    public void cure(Desktop desktop,History history,BaseBiology biology,Integer num){
        if (biology instanceof BaseEntourage){
            ((BaseEntourage)biology).hp += num;
            if(((BaseEntourage)biology).hp>((BaseEntourage)biology).maxHp){
                ((BaseEntourage)biology).hp = ((BaseEntourage)biology).maxHp;
            }
        }
        if (biology instanceof BaseHero){
            ((BaseHero)biology).hp += num;
            if(((BaseHero)biology).hp>((BaseHero)biology).maxHp){
                ((BaseHero)biology).hp = ((BaseHero)biology).maxHp;
            }
        }
    }

    /**
     * 造成伤害
     * @param target
     * @param num
     */
    @Override
    public void hurt(Desktop desktop,History history,BaseBiology target, Integer num){
        if(target instanceof BaseHero){
            hurtHero(desktop,history,(BaseHero) target,num);
        }else {
            hurtEntourage(desktop,history,(BaseEntourage) target,num);
        }
    }

    private void hurtHero(Desktop desktop,History history,BaseHero target,Integer num){
        //有护甲的情况
        if(target.armor>0){
            target.armor -= num;
            if(target.armor<0){
                target.hp += target.armor;
                target.armor = 0;
            }
        }else {
            target.hp -= num;
        }
    }

    private void hurtEntourage(Desktop desktop,History history,BaseEntourage target,Integer num){
        target.hp -= num;
        if(target.hp<=0){
            desktop.myEntourage.remove(target);
            desktop.enemiesEntourage.remove(target);
            target.deadWords(desktop,history);
        }
    }


    /**
     * 下一回合
     */
    @Override
    public void nextTurn(Desktop desktop,History history){}
}
